home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / dskutil / colrboot.zip / COLRBOOT.A86 < prev    next >
Text File  |  1994-10-29  |  35KB  |  1,372 lines

  1. ;----------------------------------------------------------------
  2. ; COLRBOOT.A86 - Puts a color message on last four sectors of disk
  3. ; and rewrites sector so message will display if the disk is booted.
  4. ; For A86V371 assembler 28 July 1994
  5. ; Revised for text 3 August 1994
  6. ; Minor revision 27 October 1994
  7.  
  8. ; This will assemble with A86 VERSION 3.71
  9. ;    A86 COLRBOOT.A86
  10.  
  11. ; JIM TUCKER    4/635 Brighton Road, Seacliff
  12. ;        South Australia, AUSTRALIA 5051 Phone: 61 8 377-1175
  13. ;        jtucker@adam.com.au
  14.  
  15. ;----------------------------------------------------------------
  16.  
  17. lf    equ    10
  18. cr    equ    13
  19. eom    equ    '$'
  20.  
  21. ;   BIOS LOADS BOOT SECTOR Entry:
  22. ;   CS:IP - 0:7C00h
  23. ;      DL - boot drive
  24. ;   ES:SI - Ptr to partition table boot entry (if hard disk)
  25. ;   All other registers undefined
  26.  
  27. bytes_per_sec   equ     word ptr [bp+0bh]
  28. sec_per_cluster equ     byte ptr [bp+0dh]
  29. reserved_sec    equ     word ptr [bp+0eh]
  30. number_of_fats  equ     byte ptr [bp+10h]
  31. root_size       equ     word ptr [bp+11h]
  32. total_sec       equ     word ptr [bp+13h]
  33. media_des_byte  equ     byte ptr [bp+15h]
  34. sec_per_fat     equ     word ptr [bp+16h]
  35. sec_per_track   equ     word ptr [bp+18h]
  36. number_of_heads equ     word ptr [bp+1ah]
  37. num_hidden_sec  equ     word ptr [bp+1ch]
  38. total_sec_long  equ     word ptr [bp+20h]
  39. drive_number    equ     word ptr [bp+24h]
  40. reserved        equ     word ptr [bp+25h]
  41. extended_flag   equ     word ptr [bp+26h]
  42. vol_serial      equ     word ptr [bp+27h]
  43. vol_name        equ     word ptr [bp+2bh]
  44. boot_flag       equ     word ptr [bp+3feh]      ;OFFSET+512 for code
  45.  
  46. reloc_entry     equ     OFFSET boot_2 - 100h
  47. boot_hard_msg    equ    7900h + OFFSET hard_msg
  48. boot_floppy_msg    equ    7900h + OFFSET floppy_msg
  49. boot_halt_msg    equ    7900h + OFFSET halt_msg
  50.  
  51. ;--------------------------------------------------------------------
  52. ; Boot sector code. The existing BPB on the target disk is written here.
  53. ; The target disk *must* be DOS formatted to obtain this information.
  54. ;--------------------------------------------------------------------
  55.  
  56.         org    100h
  57. ENTRY:          jmp     signon            ;becomes jmp boot_1
  58. BOOT_DATA       db    0            ;NZ to prevent UNREG msg
  59.         db      63 dup (0)              ;leave room for BPB
  60. BOOT_DATAEND    =       $
  61.  
  62. BOOT_1:         cli
  63.         cld
  64.                 mov     ax,7A00h
  65.                 xor     bx,bx
  66.                 mov     ss,bx                   ;SS:SP = 0:7A00
  67.                 mov     sp,ax
  68.                 sti
  69.                 push    si
  70.                 push    bp
  71.                 mov     bp,ax            ;BP is new location
  72.  
  73. ; This moves all code from 7A00 to 7C00h and jumps to BOOT_2 via RETF
  74.  
  75.         mov     ds,bx                   ;DS = 0
  76.                 mov     es,bx                   ;ES = 0
  77.                 mov     di,ax                   ;Move boot code
  78.                 mov     si,7C00h
  79.                 mov     cx,100h
  80.                 rep     movsw
  81.  
  82.                 push    es                      ;Push re-entry segment
  83.                 mov     al,reloc_entry          ;  BOOT2 OFFSET on stack
  84.                 push    ax                      ;  and go there...
  85.         retf
  86.  
  87. ; The code is moved and we read the message to location 8000h
  88. ; Note MESG_LOC is the cluster number changed by installation for disk
  89. ; sizes other than 1.44M. (1.44 last sctr=2879, we use last eight sectors).
  90.  
  91. BOOT_2:        db    0B8h            ;mov ax imm16 instruction
  92. MESG_LOC    dw    2870            ;changes with disk size
  93. SKIP_MESG:    jmp    >l1            ;*** NOPPED BY AUTOBOOT
  94.         jmp    test_hard        ;    AND NOFILE
  95.  
  96. L1:        call    maths            ;do disk sums
  97.         mov    bx,8000h        ;where to put it
  98.         
  99. ; This tries to read our message file (five times)
  100.  
  101.         mov    si,5
  102. L1:        mov    dl,0            ;drive zero
  103.         mov    ax,0208h        ;read eight sectors
  104.         int    13h
  105.         jnc    done
  106.         xor    ax,ax
  107.         int    13h
  108.         dec    si
  109.         jnz    l1
  110.  
  111. ; Fall thru, if the read failed. We will not have the message code AAAAh
  112. ; and the message won't display anyway. Test for AAAAh (our code words)
  113. ; and if not found do not display anything. This prevents garbage
  114. ; display if the disk has been filled.
  115.  
  116. DONE:        mov    si,8000h        ;where it is in memry
  117.         lodsw                ;get first word
  118.         cmp    ax,0AAAAh        ;us?
  119.         je    >l1            ;yes
  120.         jmp    test_hard        ;no message to write
  121.  
  122. ; This writes the color message direct to the screen
  123.  
  124. L1:        mov    ah,0Fh            ;get video mode
  125.         int    10h
  126.         push    ax
  127.         mov    ah,0            ;clear screen
  128.         int    10h            ;  by resetting mode
  129.         pop    ax
  130.         cmp    al,3
  131.         mov    ax,0B800h
  132.         jbe    >l1        
  133.         mov    ah,0B0h            ;(al is already zero)        
  134. L1:        push    es            ;get screen segment in es
  135.         mov    es,ax
  136.         xor    di,di
  137.         push    di
  138.         pop    ds
  139.         mov    cx,25*80        ;screen size
  140.         repnz    movsw
  141.         pop    es
  142.  
  143. ; Note CURPOS can be modified on the command line by /Pnn
  144.  
  145.         db    0B6h            ;mov dh imm8 instruction
  146. CURPOS        db    21            ;cursor line (Starts at 0)
  147.         mov    dl,0            ;  and column
  148.         mov    bh,dl            ;video page zero
  149.         mov    ah,2            ;position cursor
  150.         int    10h
  151.  
  152. TEST_HARD:    mov    ah,10h            ;test for hard disk
  153.         mov    dl,80h            ;first disk only
  154.         int    13h            ;if exist
  155.         jc    >l4            ;not found
  156.  
  157. ; Note if the following JMP is nopped by installer we boot immediately
  158. ; from the hard drive.
  159.  
  160. BOOT_C:        jmp    >l9            ;** NOPPED for autoboot
  161.         push    bp
  162.         jmp    boot_hard
  163.  
  164. L9:        push    bp
  165.         mov    ah,0
  166.         int    1ah
  167.         db    81h,0C2h    ;add dx imm16 opcode
  168. TIMER_WORD    dw    0        ;default = 1/18th secs
  169.         inc    dx        ;in case he makes it zero
  170.                     ;  and clocks rolls over
  171.         mov    bx,dx        ;  during this op
  172. L2:        int    1ah
  173.         cmp    dx,bx
  174.         jne    l2
  175.  
  176.         mov    si,boot_hard_msg    ;wanna boot it?    
  177.         call    bprint_msg
  178.  
  179. L21:        mov    ah,1            ;clear kboard buffer
  180.         int    16h            ;  in case he hit keys
  181.         jz    >l3            ;  during time delay
  182.         xor    ah,ah            ;ah=0
  183.         int    16h
  184.         jmp    l21
  185.  
  186. L3:        xor    ah,ah            ;BIOS get key
  187.         int    16h
  188.         or    al,20h
  189.         cmp    al,'y'
  190.         je    boot_hard        ;yes
  191.         cmp    al,'n'
  192.         jne    l3
  193.  
  194. ; Fall thru to boot from floppy
  195.  
  196. L4:        mov    si,boot_floppy_msg    ;wants floopy boot
  197.         call    bprint_msg
  198.         mov    ah,0            ;wait for a key
  199.         int    16h
  200.         call    clear_screen
  201.         int    19h            ;warm boot
  202.  
  203. ; This reads drive C: sector zero into 7C00h and jumps there
  204.  
  205. BOOT_HARD:    call    clear_screen
  206.         pop    bp
  207.         call    boot_read_disk
  208.         jc      boot_error
  209.  
  210.         cmp     boot_flag,0AA55h        ;Check for boot sig
  211.                 jne     boot_error
  212.                 pop     bp                      ;Restore BP from entry
  213.                 pop     si                      ;  Is BP for DR-DOS only?
  214.         jmp     bx                      ;Jump to new boot rec
  215.  
  216. ;Clear the screen
  217.  
  218. CLEAR_SCREEN:    mov    ah,0Fh        ;get video mode
  219.         int    10h
  220.         mov    ah,0        ;set video mode
  221.         int    10h
  222.         ret
  223.  
  224. BOOT_ERROR:    mov     si,boot_halt_msg        ;Print err message
  225. BOOT_ERROR1:    call    bprint_msg
  226. BOOT_HALT:    jmp     boot_halt               ;STOP!
  227.  
  228. ;-----------------------------------------------------------------------
  229. ; BOOT_READ_DISK: Reads one sector from the hard disk
  230. ;          CF - Clear if read successful.
  231. ;-----------------------------------------------------------------------
  232.  
  233. BOOT_READ_DISK: xor     ax,ax                   ;Read boot sector
  234.         call    maths
  235.         mov    bx,7C00h        ;where to put it
  236.  
  237. L1:        mov     dl,80H            ;80h is first hard disk
  238.         mov     ax,0201h        ;read one sector
  239.                 int     13h
  240.                 jnc     ret            ;no error, exit
  241.                 xor     ax,ax                   ;reset disk before reading
  242.                 int     13h
  243.                 dec     si
  244.                 jnz     l1
  245.                 mov     si,boot_halt_msg    ;read error message
  246.                 stc
  247.         ret
  248.  
  249. ; This does some calculations common to both disk reads
  250.  
  251. MATHS:        cwd
  252.         div    sec_per_track
  253.         inc    dx
  254.         mov    bx,dx
  255.         cwd
  256.         div    number_of_heads
  257.         xchg    ah,al
  258.         mov    cl,6
  259.         shl    al,cl
  260.         xchg    cx,ax
  261.         or    cl,bl
  262.         mov    dh,dl
  263.         mov    si,5
  264.         ret
  265.  
  266. ;--------------------------------------------------------------------
  267. ; BPRINT_MSG: - Prints a message to the screen
  268. ; Entry: DS:SI - Points to ASCIIZ message
  269. ;--------------------------------------------------------------------
  270.  
  271. BPRINT_MSG:    push    bx
  272.                 push    bp
  273. L1:        lodsb
  274.                 or      al,al
  275.                 je      >l2
  276.                 mov     ah,0eh
  277.                 mov     bx,7h
  278.                 push    si
  279.                 int     10h
  280.                 pop     si
  281.                 jmp     l1
  282. L2:        pop     bp
  283.                 pop     bx
  284.                 ret
  285.  
  286. HALT_MSG    db    'CANNOT BOOT - SYSTEM HALTED  ',0
  287. FLOPPY_MSG    db    cr,lf
  288.         db    'Non-System disk. Replace and ',cr,lf
  289.         db    'press any key when ready     ',0
  290. HARD_MSG    db    'Boot from hard disk (Y/N)?   ',0
  291.  
  292. BOOTCODE_END    = $
  293. SPARE_DATA    = 2FEh-BOOTCODE_END        
  294.         db    spare_data dup ' '
  295.         org     2FEh
  296.                 dw      0AA55h
  297.  
  298. ;****************************************************************
  299. ; START OF INSTALLATION CODE
  300. ;****************************************************************
  301.  
  302. IBM_SYS        db    'A:IBMBIO.COM',0
  303. MS_SYS        db    'A:IO.SYS',0    
  304. AUTOBOOT    db    'AUTOBOOT',0
  305. NOFILE        db    'NOFILE',0
  306. BLANK        db    'BLANK',0
  307. TARGET_DISK    db      0
  308. REGISTER_BYTE    db    ?
  309. VIDEO_SEG    dw    0B800h
  310. OLD_VIDEO_SEG    dw    0B800h
  311. MONO_SWITCH    db    0
  312. VIDEO_MODE    db    ?
  313.  
  314. SIGNON:        mov    dx,OFFSET hello
  315.         mov    ah,9
  316.         int    21h
  317.  
  318.         call    clear_buffers        ;intialise to zero
  319.         call    cmdline            ;sort it out
  320.         call    check_register        ;/R to prevent display
  321.         call    check_video        ;/M for mono?
  322.         call    check_curpos        ;see if cursor positioned
  323.         call    check_timer        ;see if timer set
  324.         call    check_color        ;see if color for text
  325.         call    check_filename        ;want it displayed?
  326.         call    read_file1        ;check the filename etc
  327.         call    read_file2        ;read text file if any
  328.         call    get_target        ;handle A: or B:
  329.         call    check_sys        ;ensure not a system disk
  330.         call    get_size        ;how big is it?
  331.         call    verify            ;check sectors are free
  332.         call    write_message        ;write our message
  333.         call    write_boot        ;write the boot sector
  334.  
  335.         mov    dx,OFFSET done_message
  336.         mov    ah,9
  337.         int    21h
  338.         mov    ax,4C00h
  339.         int    21h
  340.  
  341. ;----------------------------------------------------------------
  342. ; Clears buffers to zero bytes
  343. ;----------------------------------------------------------------
  344.  
  345. CLEAR_BUFFERS:    mov    di,TEXT_FILE_BUFFER
  346.         mov    ax,0
  347.         mov    cx,1000
  348.         rep    stosw
  349.         mov    ah,[103h]
  350.         mov    register_byte,ah
  351.         ret
  352.  
  353. ;----------------------------------------------------------------
  354. ; Check registered
  355. ;----------------------------------------------------------------
  356.  
  357. CHECK_REGISTER: mov    si,OFFSET switch_buffer
  358. L2:        lodsb
  359. L3:        or    al,al            ;end
  360.         jz    ret            ;yes
  361.         cmp    al,'/'            ;switch
  362.         jne    l2            ;no
  363.         lodsb                ;get
  364.         cmp    al,'R'            ;us?
  365.         jne    l3            ;no, maybe zero
  366.         mov    register_byte,1        ;set reg byte
  367.         ret
  368.  
  369. ;----------------------------------------------------------------
  370. ; CHECK_VIDEO: This checks if user wants mono display
  371. ;----------------------------------------------------------------
  372.  
  373. CHECK_VIDEO:    mov    ah,0Fh            ;get current mode
  374.         int    10h            ;video
  375.         mov    video_mode,al        ;save current mode
  376.         cmp    al,7            ;is it mono?
  377.         jne    >l1            ;no
  378.         mov    ax,0B000h
  379.         mov    video_seg,ax        ;change seg
  380.         mov    old_video_seg,ax
  381.  
  382. L1:        mov    si,OFFSET switch_buffer
  383. L2:        lodsb
  384. L3:        or    al,al            ;end
  385.         jz    ret            ;yes
  386.         cmp    al,'/'            ;switch
  387.         jne    l2            ;no
  388.         lodsb                ;get
  389.         cmp    al,'M'            ;us?
  390.         jne    l3            ;no, maybe zero
  391.         mov    mono_switch,1        ;set mono switch
  392.         ret
  393.  
  394. ;----------------------------------------------------------------
  395. ; CHECK_CURPOS: This checks for optional cursor position /Pnn
  396. ;----------------------------------------------------------------
  397.  
  398. TEN        dw    10
  399. CHECK_CURPOS:    mov    si,OFFSET switch_buffer
  400. L1:        lodsb                ;get
  401. L2:        or    al,al            ;done?
  402.         jz    ret            ;yes
  403.         cmp    al,'/'            ;switch?
  404.         jne    l1            ;no
  405.         lodsb                ;get
  406.         cmp    al,'P'            ;us?
  407.         jne    l2            ;no, maybe zero
  408.  
  409.         mov    al,[si]            ;get next
  410.         or    al,al            ;zero
  411.         jz    bad_curpos        ;error
  412.         cmp    al,'='            ;=?
  413.         jne    >l2            ;no, assume digit
  414.         inc    si            ;scrub it
  415.  
  416. L2:        xor    ax,ax            ;arithmetic
  417.         xor    bx,bx
  418.         xor    dx,dx
  419.  
  420. L3:        mov    bl,[si]
  421.         or    bl,bl
  422.         jz    >l4
  423.         cmp    bl,'/'
  424.         je    >l4
  425.         
  426.         inc    si
  427.         sub    bl,'0'
  428.         jc    bad_curpos
  429.         cmp    bl,9
  430.         ja    bad_curpos
  431.         mul    ten
  432.         add    ax,bx
  433.         jmp    l3
  434.  
  435. L4:        dec    al
  436.         mov    curpos,al
  437.         ret
  438.  
  439. BAD_CURPOS:    mov    dx,OFFSET bad_curpos_mesg
  440.         jmp    error_message
  441.  
  442.  
  443. ;----------------------------------------------------------------
  444. ; CHECK_TIMER: This checks for optional time out /Tnn
  445. ;----------------------------------------------------------------
  446.  
  447. TICKS_PER_SEC    dw    18
  448. CHECK_TIMER:    mov    si,OFFSET switch_buffer
  449. L1:        lodsb                ;get
  450. L2:        or    al,al            ;done?
  451.         jz    ret            ;yes
  452.         cmp    al,'/'            ;switch?
  453.         jne    l1            ;no
  454.         lodsb                ;get
  455.         cmp    al,'T'            ;us?
  456.         jne    l2            ;no, maybe zero
  457.  
  458.         mov    al,[si]            ;get next
  459.         or    al,al            ;zero
  460.         jz    bad_timer        ;error
  461.         cmp    al,'='            ;=?
  462.         jne    >l2            ;no, assume digit
  463.         inc    si            ;scrub it
  464.  
  465. L2:        xor    ax,ax            ;arithmetic
  466.         xor    bx,bx
  467.         xor    dx,dx
  468.  
  469. L3:        mov    bl,[si]
  470.         or    bl,bl
  471.         jz    >l4
  472.         cmp    bl,'/'
  473.         je    >l4
  474.         
  475.         inc    si
  476.         sub    bl,'0'
  477.         jc    bad_timer
  478.         cmp    bl,9
  479.         ja    bad_timer
  480.         mul    ten
  481.         add    ax,bx
  482.         jmp    l3
  483.  
  484. L4:        cmp    ax,60
  485.         jbe    >l5
  486.         mov    dx,OFFSET too_long_mesg
  487.         jmp    error_message
  488. L5:        mul    ticks_per_sec
  489.         mov    timer_word,ax
  490.         ret
  491.  
  492. BAD_TIMER:    mov    dx,OFFSET bad_timer_mesg
  493.         jmp    error_message
  494.  
  495. ;----------------------------------------------------------------
  496. ; CHECK_COLOR: This tests for option text color in hex
  497. ;----------------------------------------------------------------
  498.  
  499. SIXTEEN        dw    16
  500. CHECK_COLOR:    mov    si,OFFSET switch_buffer
  501. L1:        lodsb                ;get char
  502. L2:        or    al,al            ;end?
  503.         jz    ret            ;yes
  504.         cmp    al,'/'            ;switch?
  505.         jne    l1            ;no
  506.         lodsb                ;get next
  507.         cmp    al,'C'            ;us?
  508.         jne    l2            ;no
  509.  
  510.         mov    al,[si]            ;next
  511.         or    al,al            ;end?
  512.         jz    show_colors        ;yes
  513.         cmp    al,'='            ;this?
  514.         jne    >l2            ;no, assume digit
  515.         inc    si            ;lose it
  516.  
  517. L2:        xor    ax,ax            ;arithmetic
  518.         xor    bx,bx
  519.         xor    dx,dx
  520.  
  521. L3:        mov    bl,[si]
  522.         or    bl,bl
  523.         je    >l5
  524.         cmp    bl,'/'
  525.         je    >l5
  526.         
  527.         inc    si
  528.         xchg    ax,bx
  529.         call    caps
  530.         xchg    bx,ax
  531.  
  532.         sub    bl,'0'
  533.         jc    show_colors
  534.         cmp    bl,9
  535.         jbe    >l4
  536.  
  537.         sub    bl,7
  538.         jc    show_colors
  539.         cmp    bl,15
  540.         ja    show_colors
  541.  
  542. L4:        mul    sixteen
  543.         add    ax,bx
  544.         jmp    l3
  545.  
  546. L5:        or    ax,ax
  547.         jz    show_colors
  548.         or    dx,dx
  549.         jnz    show_colors
  550.         or    ah,ah
  551.         jnz    show_colors
  552.  
  553.         mov    text_color,al
  554.         ret
  555.  
  556. SHOW_COLORS:    jmp    display_color_help
  557.  
  558. ;----------------------------------------------------------------
  559. ; CHECK_FILENAME: This checks if user want filenames displayed
  560. ;----------------------------------------------------------------
  561.  
  562. FILENAME_SWITCH    db    0
  563.  
  564. CHECK_FILENAME:    mov    si,OFFSET switch_buffer
  565. L1:        lodsb
  566.         cmp    al,0
  567.         je    ret
  568.         cmp    al,'/'
  569.         jne    l1
  570.         lodsb
  571.         cmp    al,'F'
  572.         jne    l1
  573.  
  574.         mov    filename_switch,1
  575.         ret
  576.  
  577. ;----------------------------------------------------------------
  578. ; READ_FILE1: This reads the user file specified on the command line
  579. ;             If AUTOBOOT NOFILE or BLANK set NOPs in boot sector 
  580. ;----------------------------------------------------------------
  581.  
  582. LENGTH        dw    ?
  583. READ_FILE1:    test    W filename1
  584.         if z    jmp help        ;no file
  585.  
  586. ; This checks for AUTOBOOT
  587.  
  588.         mov    si,filename1
  589.         mov    di,OFFSET autoboot
  590.         mov    cx,8
  591. L1:        cmpsb
  592.         jne    >l2
  593.         loop    l1
  594.         mov    di,OFFSET boot_c    ;NO PROMPT FOR C
  595.         mov    ax,9090h        ;NOP NOP
  596.         stosw
  597.         mov    di,OFFSET skip_mesg    ;NO MESSAGE DISPLAY
  598.         stosw                ;NOP NOP
  599.         mov    W signature,0
  600.         test    B drive1
  601.         if z    jmp help    
  602.         ret
  603.  
  604. ; This checks for NOFILE
  605.  
  606. l2:        mov    si,filename1
  607.         mov    di,OFFSET nofile
  608.         mov    cx,6
  609. L3:        cmpsb
  610.         jne    >l4
  611.         loop    l3
  612.         mov    di,OFFSET skip_mesg    ;NO MESSAGE DISPLAY
  613.         mov    ax,9090h        ;NOP NOP
  614.         stosw
  615.         mov    W signature,0
  616.         test    B drive1
  617.         if z    jmp help
  618.         ret
  619.  
  620. ; This checks for BLANK
  621.  
  622. l4:        mov    si,filename1
  623.         mov    di,OFFSET blank
  624.         mov    cx,5
  625. L5:        cmpsb
  626.         jne    >l1
  627.         loop    l5
  628.  
  629.         mov    di,COLOR_FILE_BUFFER
  630.         mov    cx,2000
  631.         mov    ah,text_color
  632.         mov    al,20h
  633.         rep    stosw
  634.         jmp    >l0
  635.  
  636. ; No AUTOBOOT, NOFILE, BLANK so we must have a filename
  637.  
  638. L1:        mov     dx,filename1        ;open
  639.         mov    ax,3D00h
  640.         int    21h
  641.         jnc    >l2
  642.         mov    dx,OFFSET no_file_mesg
  643.         jmp    error_message
  644.  
  645. L2:        mov    bx,ax            ;get length
  646.         mov    ax,4202h
  647.         mov    cx,0
  648.         mov    dx,0
  649.         int    21h
  650.         mov    length,ax
  651.         jnc    >l3
  652.         mov    dx,OFFSET bad_size_mesg
  653.         jmp    error_message
  654.  
  655. L3:        cmp    ax,4000            ;test length
  656.         je    >l4
  657.         mov    dx,OFFSET bad_size_mesg
  658.         jmp    error_message
  659.  
  660. L4:        mov    ax,4200h        ;rewind it
  661.         mov    cx,0
  662.         mov    dx,0
  663.         int    21h
  664.  
  665.         mov    ax,3F00h        ;read file
  666.         mov    cx,length
  667.         mov    dx,COLOR_FILE_BUFFER
  668.         int    21h
  669.         jnc    >l5
  670.         mov    dx,OFFSET read_err_mesg
  671.         jmp    error_message
  672.  
  673. L5:        mov    ah,3Eh            ;close file
  674.         int    21h
  675.  
  676. ; Now insert the prompt blanks on the color screen
  677.  
  678. L0:        mov    ah,0            ;put the prompt at /P
  679.         mov    al,curpos
  680.         cmp    al,24            ;0-24
  681.         ja    >l3            ;off the screen
  682.  
  683.         mov    cl,al
  684.         xor    dx,dx
  685.         mov    bx,160            ;bytes per line
  686.         mul    bx
  687.         mov    di,ax            ;is here
  688.         add    di,COLOR_FILE_BUFFER
  689.  
  690.         mov    ax,0720h
  691.         cmp    cl,24            ;remember 0-24
  692.         je    >l2            ;just do one
  693.         cmp    cl,23            ;two to do?
  694.         je    >l1            ;yes
  695.  
  696.         mov    cx,30
  697.         rep    stosw
  698.         add    di,100
  699.  
  700. L1:        mov    cx,30
  701.         rep    stosw
  702.         add    di,100
  703.  
  704. L2:        mov    cx,30
  705.         rep    stosw
  706.  
  707. L3:        mov    dx,OFFSET reading_mesg
  708.         call    print_message
  709.         ret
  710.  
  711. ;----------------------------------------------------------------
  712. ; READ_FILE2: This reads the SECOND file if specified
  713. ;----------------------------------------------------------------
  714.  
  715. GRID_NAME    db    'GRID',0
  716. READ_FILE2:    test    W filename2
  717.         jz    ret            ;there isn't one
  718.         
  719. ; Test if he is requesting a grid
  720.  
  721.         mov    si,filename2
  722.         mov    di,OFFSET grid_name
  723.         mov    cx,4
  724. L1:        cmpsb
  725.         jne    >l2
  726.         loop    l1
  727.         jmp    write_grid
  728.  
  729. L2:        mov    dx,filename2        ;open file
  730.         mov    ax,3d00h
  731.         int    21h
  732.         jnc    >l1
  733.         mov    dx,OFFSET no_text_mesg
  734.         jmp    error_message
  735.  
  736. L1:        mov    bx,ax            ;get length
  737.         mov    ax,4202h
  738.         mov    cx,0
  739.         mov    dx,0
  740.         int    21h
  741.         mov    length,ax
  742.         jnc    >l2
  743.         mov    dx,OFFSET bad_size_mesg
  744.         jmp    error_message
  745.  
  746. L2:        cmp    ax,2000            ;test for size
  747.         jbe    >l3
  748.         mov    dx,OFFSET bad_size_mesg2
  749.         jmp    error_message
  750.  
  751. L3:        mov    ax,4200h        ;rewind it
  752.         mov    cx,0
  753.         mov    dx,0
  754.         int    21h
  755.  
  756.         mov    ax,3F00h        ;read file
  757.         mov    cx,length
  758.         mov    dx,TEXT_FILE_BUFFER
  759.         int    21h
  760.         jnc    >l4
  761.         mov    dx,OFFSET read_err_mesg
  762.         jmp    error_message
  763.  
  764. L4:        mov    ah,3eh            ;close file
  765.         int    21h
  766.  
  767.         mov    dx,OFFSET reading_mesg2
  768.         call    print_message
  769.         jmp    overlay_text
  770.  
  771. ; Now lay it on top of the color message
  772.  
  773. LINE_NUMBER    dw    0
  774. BYTES_PER_LINE    dw    160
  775. PROMPT_FLAG    db    0            ;this is set if writing
  776. TEXT_COLOR    db    07h            ;set by /Cnn switch
  777. CHAR_COUNT    db    0            ;so we don't bust a line
  778.  
  779. WRITE_GRID:    mov    si,OFFSET grid        ;lay down the grid
  780.         call    overlay            ;and come back for prompt
  781.  
  782. WRITE_PROMPT:    mov    ah,0            ;put the prompt
  783.         mov    al,curpos        ; according to /P
  784.         dec    ax            ;prompt starts with a cr
  785.         mov    line_number,ax        ;force it here
  786.         inc    prompt_flag
  787.         mov    si,OFFSET grid_prompt    ;source
  788.         jmp    overlay            ;and return to main
  789.  
  790. OVERLAY_TEXT:    mov    si,TEXT_FILE_BUFFER
  791. OVERLAY:    mov    di,COLOR_FILE_BUFFER
  792.  
  793. L1:        lodsb                ;get char from text buffer
  794.         cmp    al,cr            ;new line?
  795.         je    >l3            ;yes
  796.         cmp    al,lf            ;ignore lf
  797.         je    l1
  798.         cmp    al,0            ;end of it?
  799.         je    ret
  800.  
  801.         cmp    al,'_'
  802.         jne    >l2
  803.         add    di,2
  804.         jmp    l1
  805.  
  806. L2:        inc    char_count
  807.         cmp    char_count,80
  808.         ja    l1
  809.  
  810.         stosb                ;save it
  811.         mov    al,text_color        ;make it /Cnn
  812.         test    prompt_flag        ;unless it's the prompt...
  813.         jz    >l21
  814.         mov    al,07h
  815. L21:        stosb
  816.         jmp    l1            ;do more        
  817.  
  818. L3:        mov    char_count,0
  819.         inc    line_number        ;new line
  820.         mov    ax,line_number        ;here
  821.         cmp    ax,25            ;past end?
  822.         ja    ret
  823.         mul    bytes_per_line        ;position of next line
  824.         mov    di,ax            ;is here
  825.         add    di,COLOR_FILE_BUFFER
  826.         jmp    l1            ;do more
  827.         ret
  828.  
  829. ;----------------------------------------------------------------
  830. ; GET_TARGET: This puts the target drive in TARGET_DISK and IO NAMES
  831. ; Return if A: (default) or error if <> B:
  832. ;----------------------------------------------------------------
  833.  
  834. GET_TARGET:    mov    al,drive1 B
  835.         test    al
  836.         if z    jmp display_file
  837.         cmp    al,'A'
  838.         je    ret
  839.         cmp    al,'B'
  840.         je    >l1
  841.         mov    dx,OFFSET bad_target_mesg
  842.         jmp    error_message
  843.  
  844. L1:        mov    target_disk,1
  845.         mov    ibm_sys,'B'
  846.         mov    ms_sys,'B'
  847.         ret
  848.  
  849. ;----------------------------------------------------------------
  850. ; CHECK_SYS: This checks if system is on the target disk by trying
  851. ; to open two files.
  852. ;----------------------------------------------------------------
  853.  
  854. CHECK_SYS:    mov    dx,OFFSET target_mesg
  855.         call    print_message
  856.  
  857.         mov    dx,OFFSET ibm_sys    ;check for ibmio.com    
  858.         mov    ax,3D00h
  859.         int    21h
  860.         jnc    >l1
  861.         mov    dx,OFFSET ms_sys    ;check for io.sys
  862.         mov    ax,3D00h
  863.         int    21h
  864.         jc    ret
  865. L1:        mov    dx,OFFSET system_mesg
  866.         jmp    error_message
  867.         ret
  868.  
  869. ;----------------------------------------------------------------
  870. ; GET_SIZE: This establishes the size of the target disk and the
  871. ; sector we will use for the color message
  872. ;----------------------------------------------------------------
  873.  
  874. GET_SIZE:    mov    dl,target_disk
  875.         inc    dl
  876.         mov    ah,36h
  877.         int    21h
  878.         mov    bx,dx
  879.         xor    dx,dx            ;sec per cluster
  880.         mul    cx            ;times bytes per sec
  881.         cmp    dx,0
  882.         jne    size_error
  883.         mul    bx            ;number of clusters
  884.  
  885.         add    ax,dx            ;ah=ax al=dx
  886.         cmp    ax,3E16h        ;ie 0016:3E00=1457664
  887.         je    size_144
  888.         cmp    ax,240Bh
  889.         je    size_720
  890.         cmp    ax,8805h
  891.         je    size_360
  892.         cmp    ax,8612h
  893.         je    size_12
  894.  
  895. SIZE_ERROR:    mov    dx,OFFSET wrong_disk_mesg
  896.         jmp    error_message
  897.  
  898. SIZE_144:    mov    dx,OFFSET size_144_mesg        ;2870 already there
  899.         jmp    >l1
  900. SIZE_720:    mov    mesg_loc,1360
  901.         mov    dx,OFFSET size_720_mesg
  902.         jmp    >l1
  903. SIZE_360:    mov    mesg_loc,710
  904.         mov    dx,OFFSET size_360_mesg
  905.         jmp    >l1
  906. SIZE_12:    mov    mesg_loc,2390
  907.         mov    dx,OFFSET size_12_mesg
  908.  
  909. L1:        call    print_message
  910.         ret
  911.  
  912. ;----------------------------------------------------------------
  913. ; VERIFY: Sends a warning message if data .ne. F6h on target sector
  914. ; by doing an absolute read to the sector
  915. ;----------------------------------------------------------------
  916.  
  917. VERIFY:        mov    ax,signature W
  918.         cmp    ax,0AAAAh
  919.         jne    ret
  920.  
  921.         mov    al,target_disk
  922.         mov    cx,1
  923.         mov    dx,mesg_loc
  924.         mov    bx,VERIFY_BUFFER
  925.         int    25h
  926.         pop    bx            ;stack garbage
  927.         jnc    >l1
  928.         call    seterrmsg
  929.         jmp    init_error
  930.  
  931. L1:        mov    si,VERIFY_BUFFER
  932.         lodsw
  933.         cmp    ax,0F6F6h
  934.         je    ret
  935.  
  936.         mov    dx,OFFSET verify_mesg    ;want to continue?
  937.         call    print_message
  938. L2:        mov    ah,8            ;wait for a key
  939.         int    21h
  940.         or    al,20h
  941.         cmp    al,'y'
  942.         je    ret
  943.         cmp    al,'n'
  944.         jne    l2
  945.         mov    dx,OFFSET abort_mesg
  946.         jmp    error_message
  947.  
  948. ;----------------------------------------------------------------
  949. ; WRITE_MESSAGE: This writes the message to the disk unless the
  950. ; signature has been zapped
  951. ;----------------------------------------------------------------
  952.  
  953. UNREG_MSG db ' '-64,'U'-64,'N'-64,'R'-64,'E'-64,'G'-64,'I'-64
  954.       db 'S'-64,'T'-64,'E'-64,'R'-64,'E'-64,'D'-64,' '-64
  955.  
  956. WRITE_MESSAGE:
  957.  
  958. ; THIS WRITES AN UNREGISTERED MESSAGE
  959.  
  960.         test    register_byte
  961.         jnz    >l2
  962.  
  963.         mov    di,OFFSET signature
  964.         add    di,4000-26
  965.         mov    ah,01Eh+80h
  966.         mov    bx,OFFSET UNREG_MSG
  967.         mov    cx,14
  968. L1:        mov    al,[bx]
  969.         inc    bx
  970.         add    al,64
  971.         stosw
  972.         loop    l1
  973.  
  974. L2:        mov    ax,signature W
  975.         cmp    ax,0AAAAh
  976.         jne    ret
  977.  
  978.         mov    al,target_disk
  979.         mov    cx,8            ;8 sectors
  980.         mov    dx,mesg_loc
  981.         mov     bx,OFFSET signature
  982.         int     26h                     ;DOS Absolute Disk Write
  983.         pop    bx            ;stack shit
  984.         jnc    ret            ;done
  985.         call    seterrmsg
  986.         jmp    init_error
  987.  
  988. ;--------------------------------------------------------------------
  989. ; WRITE_BOOT: - Installs our boot record on the target diskette
  990. ; Exit:      CF - Set if error
  991. ;            DX - OFFSET of error message if CF set
  992. ;--------------------------------------------------------------------
  993.  
  994. WRITE_BOOT:    mov    dx,OFFSET install_mesg
  995.         call    print_message
  996.  
  997. ; This writes a new jump at start of our boot sector (100h)
  998.  
  999.         mov     di,OFFSET entry
  1000.                 mov     al,0E9h                 ;JMP short opcode
  1001.                 stosb
  1002.                 mov     ax,OFFSET boot_1-OFFSET boot_data
  1003.                 stosw
  1004.  
  1005. ; Read the boot sector from the target disk into a buffer
  1006.  
  1007.         mov     al,target_disk        ;Get target disk
  1008.                 mov     cx,1                    ;read 1 sector
  1009.                 xor     dx,dx                   ;Sector 0
  1010.                 mov     si,dx
  1011.                 mov     bx,TARGET_BOOT_SECTOR
  1012.                 call    read_absolute
  1013.                 jc      install_error
  1014.  
  1015. ; This checks the JMP (short or long according to DOS version).
  1016.  
  1017.                 mov     si,bx                   ;point to boot rec
  1018.                 lodsb                ;get opcode
  1019.                 mov     dl,al
  1020.                 lodsw                ;get where to
  1021.                 mov     bx,si            ;next address
  1022.                 cmp     dl,0EBh                 ;short JMP?
  1023.                 jne     >l1            ;no
  1024.                 xor     ah,ah                   ;if short JMP clear
  1025.                 jmp     >l2            ;  high byte
  1026.  
  1027. L1:        cmp     dl,0E9h                 ;Check for long JMP
  1028.         je    >l2                
  1029.         mov     dx,OFFSET not_dos_mesg
  1030.         jmp    error_message
  1031.  
  1032. L2:        mov     dx,OFFSET cant_write_mesg
  1033.                 dec     ax
  1034.                 cmp     ax,OFFSET boot_dataend - OFFSET entry
  1035.         if a    jmp error_message
  1036.  
  1037. ; This copies the boot data from target disk to our boot
  1038.  
  1039.         mov     si,bx
  1040.                 mov     di,OFFSET boot_data     ;copy boot data to
  1041.                 mov     cx,ax                   ;  boot rec
  1042.                 rep     movsb
  1043.  
  1044. ; This writes the boot sector to the target disk
  1045.  
  1046.         mov     al,target_disk        ;Get target disk
  1047.                 mov     bx,OFFSET entry
  1048.                 mov     cx,1                    ;1 sector
  1049.         xor     dx,dx                   ;Sector 0
  1050.                 xor     si,si
  1051.                 call    write_absolute          ;Write new boot rec
  1052.         jc    install_error
  1053.         ret
  1054.  
  1055. INSTALL_ERROR:    call    seterrmsg
  1056. INIT_ERROR:    call    print_msg
  1057.         mov    ax,4C01h
  1058.         int    21h
  1059.  
  1060. ;--------------------------------------------------------------------
  1061. ; READ ABSOLUTE - Reads sectors from the disk.
  1062. ; Entry:   AL - Drive to read
  1063. ;          CX - Number of sectors to read.
  1064. ;       SI,DX - Sector to start read (SI only used on huge disks)
  1065. ;       DS:BX - Pointer to data buffer.
  1066. ;--------------------------------------------------------------------
  1067.  
  1068. READ_ABSOLUTE:    push    bx
  1069.                 push    cx
  1070.                 push    ds
  1071.         int     25h                     ;DOS Absolute Disk Read
  1072.                 pop     bx                      ;stack shit
  1073.                 call    seterrmsg
  1074.                 cld
  1075.         pop     ds
  1076.                 pop     cx
  1077.                 pop     bx
  1078.                 ret
  1079.  
  1080. ;--------------------------------------------------------------------
  1081. ; WRITE ABSOLUTE - Writes sectors to the disk.
  1082. ; Entry:   AL - Drive to write
  1083. ;          CX - Number of sectors to write
  1084. ;       SI,DX - Sector to start write (SI only used on huge disks)
  1085. ;       DS:BX - Pointer to data buffer.
  1086. ;--------------------------------------------------------------------
  1087.  
  1088. WRITE_ABSOLUTE:    push    bx
  1089.                 push    cx
  1090.                 push    ds
  1091.         int     26h                     ;DOS Absolute Disk Write
  1092.                 pop     bx                      ;statck shit
  1093.                 call    seterrmsg
  1094.                 cld
  1095.         pop     ds
  1096.                 pop     cx
  1097.                 pop     bx
  1098.                 ret
  1099.  
  1100. ;----------------------------------------------------------------
  1101. ; Sundry routines used by the above
  1102. ;----------------------------------------------------------------
  1103.  
  1104. CAPS:        cmp    al,'a'
  1105.         jb    ret
  1106.         cmp    al,'z'
  1107.         ja    ret
  1108.         and    al,5Fh
  1109.         ret
  1110.  
  1111. PRINT_MESSAGE:    push    ax
  1112.         mov    ah,9
  1113.         int    21h
  1114.         pop    ax
  1115.         ret
  1116.  
  1117. HELP:        JMP    DISPLAY_SCREEN
  1118.  
  1119. ERROR_MESSAGE:    call    print_message
  1120.         mov    ax,4C01h
  1121.         int    21h
  1122.  
  1123. ;----------------------------------------------------------------
  1124. ; MESSAGE DATA
  1125. ;----------------------------------------------------------------
  1126.  
  1127. NO_FILE_MESG    db    'Color file not found',7,cr,lf,eom
  1128. NO_TEXT_MESG    db    'Text file not found',7,cr,lf,eom
  1129. BAD_TARGET_MESG    db    'Invalid target drive',7,cr,lf,eom
  1130. SYSTEM_MESG    db    'Target contains system files. Aborted.',7,cr,lf,eom
  1131. TARGET_MESG    db    'Verifying target disk',cr,lf,eom
  1132. WRONG_DISK_MESG db    'Wrong size disk',7,cr,lf,eom
  1133. VERIFY_MESG    db    'WARNING! Message sector may contain data. Continue (Y/N)?',7,cr,lf,eom
  1134. ABORT_MESG    db    'Aborted as user request',cr,lf,eom
  1135. SIZE_144_MESG    db    '1.44Mb disk detected',cr,lf,eom
  1136. SIZE_720_MESG    db    '720Kb disk detected',cr,lf,eom
  1137. SIZE_360_MESG    db    '360Kb disk detected',cr,lf,eom
  1138. SIZE_12_MESG    db    '1.2Mb disk detected',cr,lf,eom
  1139. READING_MESG    db    'Reading color file',cr,lf,eom
  1140. READING_MESG2    db    'Reading text file',cr,lf,eom
  1141. BAD_SWITCH_MESG db    'Invalid switch',7,cr,lf,eom
  1142. BAD_CURPOS_MESG db    'Invalid cursor /P position',cr,lf,eom
  1143. BAD_TIMER_MESG    db    'Invalid timer /T value',7,cr,lf,eom
  1144. TOO_LONG_MESG    db    'Timer delay must not exceed 60 seconds',7,cr,lf,eom
  1145. BAD_COLOR_MESG    db    'Invalid color /C specified',7,cr,lf,eom
  1146. NOT_DOS_MESG    db    'Target diskette not a DOS formatted disk',7,cr,lf,eom
  1147. CANT_WRITE_MESG db    'Cannot write code on target disk',7,cr,lf,eom
  1148. INSTALL_MESG    db    'Installing boot sector',cr,lf,eom
  1149. BAD_SIZE_MESG    db    'Bad color file size (must be 4000 bytes)',7,cr,lf,eom
  1150. BAD_SIZE_MESG2    db    'Bad text file size (maximum 2000 bytes)',7,cr,lf,eom
  1151. READ_ERR_MESG    db    'Error reading data file',7,cr,lf,eom
  1152. WRITE_ERROR    db    'Error writing data to sector address',7,cr,lf,eom
  1153. DONE_MESSAGE    db    'Disk modified OK',cr,lf,eom
  1154.  
  1155. HELLO    db    cr,lf
  1156.     db    'COLRBOOT V1.0 ■ Release November 1994 JIM TUCKER',cr,lf
  1157.     db    'Copyright (c) 1994 JIM TUCKER. All rights reserved',cr,lf,eom
  1158.  
  1159. ;----------------------------------------------------------------
  1160. ; This is the display stuff
  1161. ;----------------------------------------------------------------
  1162.  
  1163. CURSOR_SIZE    dw    ?
  1164. CURSOR_POS    dw    ?
  1165.  
  1166. ;----------------------------------------------------------------
  1167. ; This moves the COLOR_HELP screen to the OUTPUT screen
  1168. ;----------------------------------------------------------------
  1169.  
  1170. DISPLAY_COLOR_HELP:
  1171.         mov    si,OFFSET color_help
  1172.         mov    di,OFFSET output_screen
  1173.         mov    cx,2000
  1174.         rep    movsw
  1175.         jmp    display_screen
  1176.  
  1177. ;----------------------------------------------------------------
  1178. ; This moves the FILE (and any overlay) to the OUTPUT screen 
  1179. ;----------------------------------------------------------------
  1180.  
  1181. DISPLAY_FILE:    call    write_prompt        ; put prompt on screen
  1182.         mov    si,COLOR_FILE_BUFFER    ; get the file
  1183.         mov    di,OFFSET output_screen    
  1184.         mov    cx,2000
  1185.         rep    movsw
  1186.         test    filename_switch        ; /F switch?
  1187.         jz    display_screen        ; no
  1188.  
  1189.         mov    si,filename1        ; display filename
  1190.         mov    di,OFFSET output_screen
  1191.         add    di,4000-40
  1192.         mov    ah,0Eh        
  1193. L1:        lodsb
  1194.         test    al
  1195.         jz    display_screen
  1196.         stosw
  1197.         jmp    l1        
  1198.  
  1199. ;----------------------------------------------------------------
  1200. ; Here to display the contents of the OUTPUT screen
  1201. ;----------------------------------------------------------------
  1202.  
  1203. ; This saves the current screen - we can overwrite the file buffer
  1204. ; DS:SI is the screen, ES:DI is the buffer
  1205.  
  1206. DISPLAY_SCREEN:    mov    di,COLOR_FILE_BUFFER
  1207.         mov    ax,video_seg        ; current video
  1208.                 mov     ds, ax                  ; place in DS
  1209.                 xor     si, si                  ; zero SI
  1210.                 mov     cx, 2000
  1211.                 rep    movsw            ; store chars and color
  1212.         mov    ds,cs            ; done, restore DS
  1213.  
  1214. ; Save the cursor info
  1215.  
  1216.         mov    bh,0            ; page zero
  1217.         mov    ah,3            ; get cursor info
  1218.         int    10h
  1219.         mov    cursor_pos,dx        ; save it for restore
  1220.         mov    cursor_size,cx
  1221.  
  1222. ; Hide the cursor
  1223.  
  1224.         mov    ah,2
  1225.         mov    bh,0
  1226.         mov    dx,1A00h
  1227.         int    10h
  1228.  
  1229.         test    mono_switch
  1230.         jz    >l1
  1231.         mov    ah,0
  1232.         mov    al,7
  1233.         int    10h
  1234.         mov    ax,video_seg
  1235.         mov    old_video_seg,ax
  1236.         mov    video_seg,0B000h
  1237.  
  1238. ; This WRITES the OUTPUT screen to the VIDEO SEGMENT
  1239.  
  1240. L1:        mov    ax,video_seg
  1241.         mov    es,ax
  1242.         mov    si,offset OUTPUT_SCREEN
  1243.         xor    di,di
  1244.         mov    cx,2000
  1245.         rep    movsw
  1246.         mov    es,cs
  1247.  
  1248. L1:        mov    ah,01h        ;wait for a keystroke
  1249.         int    016h
  1250.         jz    l1
  1251.         mov    ah,0        ;clear keyboard buffer
  1252.         int    016h
  1253.  
  1254. ; Restore the screen
  1255.  
  1256.         mov    al,video_mode
  1257.         mov    ah,0
  1258.         int    10h
  1259.         mov    ax,old_video_seg
  1260.         mov    video_seg,ax
  1261.  
  1262. ; DS:SI is the buffer, ES:DI is the screen
  1263.  
  1264. L1:        mov    si,COLOR_FILE_BUFFER
  1265.         mov    ax,video_seg
  1266.         mov    es,ax
  1267.         xor    di,di
  1268.         mov    cx,2000
  1269.         rep    movsw
  1270.         mov    es,cs        
  1271.  
  1272. ; Put the cursor back
  1273.  
  1274.         mov    bh,0
  1275.         mov    dx,cursor_pos
  1276.         mov    ah,2
  1277.         int    10h
  1278.         mov    cx,cursor_size
  1279.         mov    ah,1
  1280.         int    10h
  1281.  
  1282.         mov    ax,4C00h
  1283.         int    21h
  1284.  
  1285. ;----------------------------------------------------------------
  1286. ; The following are messages returned by absolute and read and write.
  1287.  
  1288. DOSERR_TBL      dw      OFFSET  doserr_00
  1289.                 dw      OFFSET  doserr_01
  1290.                 dw      OFFSET  doserr_02
  1291.                 dw      OFFSET  doserr_03
  1292.                 dw      OFFSET  doserr_04
  1293.                 dw      OFFSET  doserr_05
  1294.                 dw      OFFSET  doserr_06
  1295.                 dw      OFFSET  doserr_07
  1296.                 dw      OFFSET  doserr_08
  1297.                 dw      OFFSET  doserr_09
  1298.                 dw      OFFSET  doserr_10
  1299.                 dw      OFFSET  doserr_11
  1300.                 dw      OFFSET  doserr_12
  1301.                 dw      OFFSET  doserr_unk
  1302. DOSERR_TBLEND   =       $
  1303.  
  1304. doserr_00       db      "Disk Write Protected",0
  1305. doserr_01       db      "Unknown Unit",0
  1306. doserr_02       db      "Drive not ready",0
  1307. doserr_03       db      "Unknown Command",0
  1308. doserr_04       db      "CRC Data Error",0
  1309. doserr_05       db      "Bad request structure",0
  1310. doserr_06       db      "Disk Seek error",0
  1311. doserr_07       db      "Not a DOS disk",0
  1312. doserr_08       db      "Sector not found",0
  1313. doserr_09       db      "Printer out of paper",0
  1314. doserr_10       db      "Disk Write fault",0
  1315. doserr_11       db      "Disk Read fault",0
  1316. doserr_12       db      "General failure",0
  1317. doserr_unk      db      "Unknown DOS error",0
  1318.  
  1319. ;--------------------------------------------------------------------
  1320. ; SETERRMSG:  Assigns a DOS error message to the value in AL
  1321. ; Entry: AL - Error code
  1322. ;        CF - Set if error
  1323. ; Exit:  SI - Points to error message
  1324. ;--------------------------------------------------------------------
  1325.  
  1326. SETERRMSG:    push    bx
  1327.                 pushf
  1328.                 jnc     >l2
  1329.                 mov     bx,ax
  1330.                 xor     bh,bh
  1331.                 shl     bx,1
  1332.                 cmp     bx,OFFSET doserr_tblend - OFFSET doserr_tbl
  1333.                 jbe     >l1
  1334.                 mov     bx,26
  1335. L1:        mov     si,[bx+doserr_tbl]
  1336. L2:        popf
  1337.                 pop     bx
  1338.                 ret
  1339.  
  1340. ;----------------------------------------------------------------
  1341. ; PRINT_MSG: Prints ASCIIZ message to screen appending crlf
  1342. ; Entry: DS:SI - Points to ASCIIZ message
  1343. ;----------------------------------------------------------------
  1344.  
  1345. CRLF_MSG        db      13,10,0
  1346. PRINT_MSG:    call    print_line
  1347.                 mov     si,OFFSET crlf_msg
  1348.                 call    print_line
  1349.                 ret
  1350.  
  1351. ;----------------------------------------------------------------
  1352. ; PRINT_LINE: Prints a line to the screen
  1353. ; Entry: DS:SI - Points to ASCIIZ message
  1354. ;----------------------------------------------------------------
  1355.  
  1356. PRINT_LINE:    lodsb
  1357.                 or      al,al
  1358.                 je      >l1
  1359.                 mov     dl,al
  1360.                 mov     ah,02
  1361.                 int     21h
  1362.                 jmp     short print_line
  1363. L1:        ret
  1364.  
  1365. ; If you do not have the latest version of A86 catenate these files
  1366. ; to this file.
  1367.  
  1368. INCLUDE CMDLINE.A86
  1369. INCLUDE CBDATA.A86
  1370.  
  1371. ; END COLRBOOT.A86
  1372.